package com.scau.os.fileSystem.memory;

import java.io.File;
import java.io.RandomAccessFile;

import com.scau.os.fileSystem.directory.Directory;
import com.scau.os.fileSystem.other.MyFileSystemException;

public enum Disk {

    INSTANCE;

    public final int SIZE = 128;
    public final int BLOCK_SIZE = 64;
    public final int ROOT_BLOCK = 2;

    private final String DISK_FILE_NAME = "disk.dat";
    private File diskFile;
    private RandomAccessFile diskAccess;

    public String getDiskFileName() {
        return DISK_FILE_NAME;
    }

    public void launch() throws Exception {
        try {
            diskFile = new File(DISK_FILE_NAME);
            diskFile.createNewFile();
            diskAccess = new RandomAccessFile(diskFile, "rw");

            initializeDisk();
        } catch (Exception e) {
            throw new MyFileSystemException("磁盘启动失败");
        }

    }

    public void initializeDisk() throws Exception {
        try {
            FAT.INSTANCE.saveToDisk();//清空缓存

            byte[] emptyBlock = new byte[BLOCK_SIZE];
            for (int i = 0; i < SIZE; i++) {
                writeBlock(i, emptyBlock);
            }
            FAT.INSTANCE.setFATItem(0, -1);
            FAT.INSTANCE.setFATItem(1, -1);
            FAT.INSTANCE.setFATItem(2, -1);
            Directory.initDirectoryEntry(ROOT_BLOCK);
        } catch (Exception e) {
            throw new MyFileSystemException("磁盘初始化失败");
        }
    }

    public byte[] readBlock(int blockNumber) throws Exception {
        try {
            byte[] data = new byte[BLOCK_SIZE];
            diskAccess.seek(blockNumber * BLOCK_SIZE);
            diskAccess.read(data);
            return data;
        } catch (Exception e) {
            throw new MyFileSystemException("磁盘读取失败");
        }
    }

    public void writeBlock(int blockNumber, byte[] data) throws Exception {
        try {
            diskAccess.seek(blockNumber * BLOCK_SIZE);
            diskAccess.write(data);
        } catch (Exception e) {
            throw new MyFileSystemException("磁盘写入失败");
        }

    }

}